<template>
  <div class="evidence-network">
    <div class="network-header">
      <h3>证据关系网络</h3>
      <div class="network-controls">
        <button class="control-btn" @click="zoomIn" title="放大">
          <i class="fas fa-search-plus"></i>
        </button>
        <button class="control-btn" @click="zoomOut" title="缩小">
          <i class="fas fa-search-minus"></i>
        </button>
        <button class="control-btn" @click="resetView" title="重置视图">
          <i class="fas fa-redo"></i>
        </button>
        <button class="control-btn" @click="toggleAutoLayout" :class="{ active: autoLayout }" title="自动布局">
          <i class="fas fa-magic"></i>
        </button>
      </div>
    </div>

    <div class="network-container" ref="chartRef">
      <!-- 图表将在这里渲染 -->
    </div>

    <div class="network-legend">
      <div class="legend-item">
        <div class="legend-color goal"></div>
        <span>目标</span>
      </div>
      <div class="legend-item">
        <div class="legend-color evidence"></div>
        <span>证据</span>
      </div>
      <div class="legend-item">
        <div class="legend-line supports"></div>
        <span>支持关系</span>
      </div>
      <div class="legend-item">
        <div class="legend-line conflicts"></div>
        <span>冲突关系</span>
      </div>
      <div v-for="user in getUniqueUsers()" :key="user" class="legend-item">
        <div class="legend-color user" :style="{ backgroundColor: getUserColor(user) }"></div>
        <span>{{ user }}</span>
      </div>
    </div>

    <!-- 节点详情弹窗 -->
    <div v-if="selectedNode" class="node-details" :style="detailsPosition">
      <div class="details-header">
        <span class="node-type">{{ selectedNode.type === 'goal' ? '目标' : '证据' }}</span>
        <button class="close-btn" @click="closeDetails">×</button>
      </div>
      <div class="details-content">
        <p class="node-label">{{ selectedNode.label }}</p>
        <div class="node-meta">
          <span class="user-tag" v-if="selectedNode.user" :style="{ backgroundColor: getUserColor(selectedNode.user) }">
            {{ selectedNode.user }}
          </span>
          <span class="weight-tag" v-if="selectedNode.weight !== undefined">
            权重: {{ selectedNode.weight }}
          </span>
        </div>
        <div class="related-nodes">
          <h4>相关{{ selectedNode.type === 'goal' ? '证据' : '目标' }}</h4>
          <ul>
            <li v-for="node in getRelatedNodes(selectedNode)" :key="node.id">
              {{ node.label }}
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';
import { useAnalysisStore } from '../../stores/analysis';
import type { NetworkNode } from '../../stores/analysis';

// 使用store
const analysisStore = useAnalysisStore();

const props = defineProps<{
  networkData?: {
    nodes: NetworkNode[];
    links: {
      source: string;
      target: string;
      type?: string;
    }[];
  }
}>();

const chartRef = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;

const selectedNode = ref<NetworkNode | null>(null);
const detailsPosition = ref({ left: '0px', top: '0px' });
const autoLayout = ref(true);

// 从store获取网络数据
const getNetworkData = () => {
  // 如果props中提供了数据，优先使用props数据
  if (props.networkData && props.networkData.nodes.length > 0) {
    return props.networkData;
  }
  // 否则使用store中的数据
  return analysisStore.getNetworkData;
};

const initChart = async () => {
  console.log('EvidenceNetwork: Initializing chart...');
  
  await nextTick();
  
  if (!chartRef.value) {
    console.error('EvidenceNetwork: Chart container not found');
    return;
  }
  
  if (chartInstance) {
    try {
      chartInstance.dispose();
    } catch (e) {
      console.error('EvidenceNetwork: Error disposing chart:', e);
    }
    chartInstance = null;
  }
  
  try {
    chartInstance = echarts.init(chartRef.value);
    
    const networkData = getNetworkData();
    
    if (!networkData.nodes || networkData.nodes.length === 0) {
      console.warn('EvidenceNetwork: No network data available');
      return;
    }

    // 准备节点数据
    const nodes = networkData.nodes.map(node => {
      // 确定节点类型 (0: 目标, 1: 证据)
      const category = node.type === 'goal' ? 0 : 1;
      
      // 根据节点类型和权重确定大小
      const baseSize = node.type === 'goal' ? 60 : 40;
      const weightFactor = node.weight ? node.weight / 5 : 1;
      const symbolSize = baseSize * Math.max(0.8, Math.min(1.5, weightFactor));
      
      // 确定节点颜色 - 使用用户颜色
      const itemStyle = {
        color: getUserColor(node.user)
      };
      
      return {
        id: node.id,
        name: node.label,
        symbolSize: symbolSize,
        category: category,
        itemStyle: itemStyle,
        // 保存原始节点数据以便点击时使用
        originData: node
      };
    });
    
    // 准备连接线数据
    const links = networkData.links.map(link => {
      // 确定连接线样式 - 支持或冲突
      const lineStyle = {
        width: 3,
        curveness: 0.2,
        color: link.type === 'conflicts' ? '#e74c3c' : '#3498db',
        type: link.type === 'conflicts' ? 'dashed' : 'solid'
      };
      
      return {
        source: link.source,
        target: link.target,
        lineStyle: lineStyle,
        // 添加连接线标签
        label: {
          show: true,
          formatter: link.type === 'conflicts' ? '冲突' : '支持',
          fontSize: 12,
          color: link.type === 'conflicts' ? '#e74c3c' : '#3498db',
          backgroundColor: 'rgba(255, 255, 255, 0.7)',
          padding: [2, 4],
          borderRadius: 3
        }
      };
    });
    
    // 准备图表配置
    const option = {
      tooltip: {
        trigger: 'item',
        formatter: function(params: any) {
          if (params.dataType === 'node') {
            const node = params.data.originData;
            return `<div style="font-weight:bold">${node.label}</div>
                    <div>类型: ${node.type === 'goal' ? '目标' : '证据'}</div>
                    <div>用户: ${node.user || '未知'}</div>
                    ${node.weight ? `<div>权重: ${node.weight}</div>` : ''}`;
          }
          return params.name;
        }
      },
      legend: {
        data: ['目标', '证据'],
        orient: 'horizontal',
        bottom: 10,
        left: 'center',
        textStyle: {
          color: '#666'
        },
        itemWidth: 15,
        itemHeight: 10,
        itemGap: 25
      },
      series: [{
        type: 'graph',
        layout: autoLayout.value ? 'force' : 'none',
        data: nodes,
        links: links,
        categories: [
          { name: '目标' },
          { name: '证据' }
        ],
        roam: true,
        draggable: true,
        label: {
          show: true,
          position: 'right',
          formatter: '{b}',
          fontSize: 12,
          color: '#333',
          backgroundColor: 'rgba(255, 255, 255, 0.7)',
          padding: [3, 5],
          borderRadius: 3
        },
        edgeLabel: {
          show: false
        },
        force: {
          repulsion: 350,
          edgeLength: 200,
          gravity: 0.1,
          layoutAnimation: true
        },
        emphasis: {
          focus: 'adjacency',
          lineStyle: {
            width: 6
          },
          label: {
            fontSize: 14,
            fontWeight: 'bold'
          }
        }
      }]
    };
    
    chartInstance.setOption(option);
    console.log('EvidenceNetwork: Chart initialized successfully');
    
    chartInstance.on('click', (params: any) => {
      if (params.dataType === 'node' && params.data) {
        const nodeId = params.data.id as string;
        const networkData = getNetworkData();
        const node = networkData.nodes.find(n => n.id === nodeId);
        if (node) {
          selectedNode.value = node;
          if (params.event) {
            detailsPosition.value = {
              left: `${params.event.offsetX + 20}px`,
              top: `${params.event.offsetY + 20}px`
            };
          }
        }
      } else {
        selectedNode.value = null;
      }
    });
    
  } catch (error) {
    console.error('EvidenceNetwork: Error initializing chart:', error);
  }
};

const handleResize = () => {
  if (chartInstance) {
    try {
      chartInstance.resize();
    } catch (e) {
      console.error('EvidenceNetwork: Error resizing chart:', e);
    }
  }
};

// 监听props变化
watch(() => props.networkData, () => {
  console.log('EvidenceNetwork: Network data changed, reinitializing chart');
  nextTick(() => {
    initChart();
  });
}, { deep: true });

// 监听store中的网络数据变化
watch(() => analysisStore.networkData, () => {
  console.log('EvidenceNetwork: Store network data changed, reinitializing chart');
  nextTick(() => {
    initChart();
  });
}, { deep: true });

onMounted(() => {
  console.log('EvidenceNetwork: Component mounted');
  window.addEventListener('resize', handleResize);
  
  // 如果store中没有数据，加载数据
  if (analysisStore.networkData.nodes.length === 0 && (!props.networkData || props.networkData.nodes.length === 0)) {
    analysisStore.loadAnalysisData();
  } else {
    // 使用延迟确保DOM已完全渲染
    setTimeout(() => {
      initChart();
    }, 500);
  }
});

onUnmounted(() => {
  console.log('EvidenceNetwork: Component unmounted');
  window.removeEventListener('resize', handleResize);
  
  if (chartInstance) {
    try {
      chartInstance.dispose();
    } catch (e) {
      console.error('EvidenceNetwork: Error disposing chart:', e);
    }
    chartInstance = null;
  }
});

const zoomIn = () => {
  if (chartInstance) {
    const option = chartInstance.getOption();
    const series = option.series as any[];
    const zoom = series[0]?.zoom || 1;
    chartInstance.setOption({
      series: [{
        zoom: Math.min(zoom * 1.5, 10)
      }]
    });
  }
};

const zoomOut = () => {
  if (chartInstance) {
    const option = chartInstance.getOption();
    const series = option.series as any[];
    const zoom = series[0]?.zoom || 1;
    chartInstance.setOption({
      series: [{
        zoom: Math.max(zoom / 1.5, 0.1)
      }]
    });
  }
};

const resetView = () => {
  if (chartInstance) {
    chartInstance.setOption({
      series: [{
        zoom: 1,
        center: ['50%', '50%']
      }]
    });
  }
};

const toggleAutoLayout = () => {
  autoLayout.value = !autoLayout.value;
  if (chartInstance) {
    chartInstance.setOption({
      series: [{
        force: {
          layoutAnimation: autoLayout.value
        }
      }]
    });
  }
};

// 根据用户获取颜色
const getUserColor = (user: string | undefined): string => {
  if (!user) return '#999';
  
  // 预定义的颜色方案
  const colorScheme = [
    '#3498db', // 蓝色
    '#e74c3c', // 红色
    '#2ecc71', // 绿色
    '#f39c12', // 橙色
    '#9b59b6', // 紫色
    '#1abc9c', // 青绿色
    '#d35400', // 深橙色
    '#34495e'  // 深蓝灰色
  ];
  
  // 使用用户名作为索引获取颜色
  const index = getUniqueUsers().indexOf(user);
  return index >= 0 ? colorScheme[index % colorScheme.length] : '#999';
};

const getRelatedNodes = (node: NetworkNode): NetworkNode[] => {
  const relatedNodes: NetworkNode[] = [];
  const networkData = getNetworkData();
  
  if (!networkData || !networkData.links) return relatedNodes;
  
  networkData.links.forEach(link => {
    if (link.source === node.id) {
      const targetNode = networkData.nodes.find(n => n.id === link.target);
      if (targetNode) relatedNodes.push(targetNode);
    } else if (link.target === node.id) {
      const sourceNode = networkData.nodes.find(n => n.id === link.source);
      if (sourceNode) relatedNodes.push(sourceNode);
    }
  });
  
  return relatedNodes;
};

const closeDetails = () => {
  selectedNode.value = null;
};

// 获取所有唯一的用户
const getUniqueUsers = () => {
  const networkData = getNetworkData();
  if (!networkData.nodes) return [];
  
  const users = new Set<string>();
  networkData.nodes.forEach(node => {
    if (node.user) {
      users.add(node.user);
    }
  });
  
  return Array.from(users);
};
</script>

<style scoped>
.evidence-network {
  position: relative;
  width: 100%;
  height: 500px;
  border-radius: 8px;
  background-color: #f9f9f9;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.network-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid #eee;
}

.network-header h3 {
  margin: 0;
  font-size: 1.2rem;
  color: #333;
}

.network-controls {
  display: flex;
  gap: 5px;
}

.control-btn {
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 5px 8px;
  cursor: pointer;
  transition: all 0.2s;
}

.control-btn:hover {
  background: #f0f0f0;
}

.control-btn.active {
  background: #8b5cf6;
  color: white;
  border-color: #8b5cf6;
}

.network-container {
  width: 100%;
  height: 400px;
}

.network-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 15px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.8);
  border-top: 1px solid #eee;
}

.legend-item {
  display: flex;
  align-items: center;
  font-size: 0.9rem;
  color: #666;
}

.legend-color {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-right: 5px;
}

.legend-color.goal {
  background-color: #3498db;
}

.legend-color.evidence {
  background-color: #2ecc71;
}

.legend-color.user {
  border-radius: 50%;
}

.legend-line {
  width: 20px;
  height: 2px;
  margin-right: 5px;
}

.legend-line.supports {
  background-color: #3498db;
}

.legend-line.conflicts {
  background-color: #e74c3c;
  border-top: 2px dashed #e74c3c;
  height: 0;
}

.node-details {
  position: absolute;
  background: white;
  border-radius: 8px;
  box-shadow: 0 3px 15px rgba(0, 0, 0, 0.1);
  width: 250px;
  z-index: 100;
  overflow: hidden;
}

.details-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  background: #8b5cf6;
  color: white;
}

.node-type {
  font-weight: bold;
  text-transform: uppercase;
  font-size: 0.8rem;
}

.close-btn {
  background: none;
  border: none;
  color: white;
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0;
  line-height: 1;
}

.details-content {
  padding: 15px;
}

.node-label {
  font-weight: bold;
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 1rem;
}

.node-meta {
  display: flex;
  gap: 8px;
  margin-bottom: 15px;
}

.user-tag, .weight-tag {
  font-size: 0.8rem;
  padding: 2px 8px;
  border-radius: 12px;
  color: white;
}

.weight-tag {
  background-color: #7f8c8d;
}

.related-nodes {
  border-top: 1px solid #eee;
  padding-top: 10px;
}

.related-nodes h4 {
  font-size: 0.9rem;
  margin: 0 0 8px 0;
  color: #555;
}

.related-nodes ul {
  margin: 0;
  padding-left: 20px;
  font-size: 0.9rem;
}

.related-nodes li {
  margin-bottom: 5px;
}

@media (max-width: 768px) {
  .evidence-network {
    height: 400px;
  }
  
  .network-container {
    height: 300px;
  }
  
  .node-details {
    width: 220px;
  }
}

/* 暗黑模式 */
@media (prefers-color-scheme: dark) {
  .evidence-network {
    background-color: #1e1e1e;
  }
  
  .network-header {
    border-bottom-color: #333;
  }
  
  .network-header h3 {
    color: #e0e0e0;
  }
  
  .control-btn {
    background: #2d2d2d;
    border-color: #444;
    color: #e0e0e0;
  }
  
  .control-btn:hover {
    background: #3d3d3d;
  }
  
  .network-legend {
    background: rgba(30, 30, 30, 0.8);
    border-top-color: #333;
  }
  
  .legend-item {
    color: #ccc;
  }
  
  .node-details {
    background: #2d2d2d;
    box-shadow: 0 3px 15px rgba(0, 0, 0, 0.3);
  }
  
  .details-content {
    color: #e0e0e0;
  }
  
  .related-nodes {
    border-top-color: #444;
  }
  
  .related-nodes h4 {
    color: #ccc;
  }
}
</style>
